// Copyright (C) 2022 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
//
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<广西木子科技有限公司>，授权编号：<NT220402151538>，代码指纹：<A.648883738.885>，技术对接人微信：<ID: Lingmuziyi>】
// 【授权寄送：<收件：李先生、地址：南宁市科园西十路11号国电智能大厦1101F、电话：17736659550、邮箱：yingshashou@vip.qq.com>】
//
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
//
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.file.d;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.httpfile.FileDownload;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.BaseConf;
import com.x52im.rainbowchat.http.logic.LogicProcessor2;

//FIXME: 在更苛刻的安全性要求下，可考虑要求客户端把token字段带上来，以便进行更强的合法身份检查
public class UserAvatarDownloader extends javax.servlet.http.HttpServlet
        implements javax.servlet.Servlet {
    /**
     * 一个1像素透明图片
     */
    public final static String ONE_PIXEL_TRANSPARENT_AVATAR_FILE_NAME = "on_pixel_transparent_avatar.png";

    /* (non-Java-doc)
     * @see javax.servlet.http.HttpServlet#HttpServlet()
     */
    public UserAvatarDownloader() {
        super();
    }

    /**
     * Servlet规范中本protected方法由public void service(,,)方法调用, 而public void service(,,)
     * 则由Web容器调用(所以它是public公共方法),因此一般情况下尽量避免重写public void service(,,)方法
     * ,而重写父类的本protedted方法则比较合理.
     */
    protected void service(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        LoggerFactory.getLog().debug("[HTTP]下载头像：你传过来的参数" +
                "action=" + req.getParameter("action")
                + ",user_uid=" + req.getParameter("user_uid")
                + ",user_local_cached_avatar=" + req.getParameter("user_local_cached_avatar")
                + ",enforceDawnload=" + req.getParameter("enforceDawnload")
                + ",one_pixel_transparent_if_no=" + req.getParameter("one_pixel_transparent_if_no")
                + ",[---- " + req.getContextPath() + "-" + req.getRequestURL() + "]");

        String action = req.getParameter("action");

        // avatar download
        if ("ad".equals(action)) {
            String userUid = req.getParameter("user_uid");
            String userLocalCachedAvatarFileName = req.getParameter("user_local_cached_avatar");

            // 是否强制下载（强制下载意味着无论用户头像用无缓存至本地，都将无条件返回该用户头像（前提是该用 户头像确实存在于服务器上））
            String _enforceDawnload = req.getParameter("enforceDawnload");
            boolean enforceDawnload = (_enforceDawnload != null && _enforceDawnload.equals("1"));

            // 此参数为“1”时，表示当用户没有设置头像时，会默认返回一个1像素透明图片（这主要用于Web网页里显示用户
            // 头像时，否则当用户没有设置头像时，因为没有图片数据返回而会在页面上显示一个“破图”img元素，那就难看
            // 死了！）
            String _onePixelTransparentIfNo = req.getParameter("one_pixel_transparent_if_no");
            boolean onePixelTransparentIfNo = (_onePixelTransparentIfNo != null && _onePixelTransparentIfNo.equals("1"));

            processAvatarDownload(res, userUid
                    , userLocalCachedAvatarFileName, enforceDawnload, onePixelTransparentIfNo);
        } else {
            LoggerFactory.getLog().warn("[HTTP]无效的action=" + action);
        }
    }

    /**
     * 用户头像HTTP下载实现方法.
     *
     * @param res
     * @param userUid
     * @param userLocalCachedAvatarFileName 用户缓存在本地的头像文件名（本参数只在enforceDawnload==false时有意义）
     * @param enforceDawnload               true表示无论客户端有无提交缓存图片名称本方法都将无条件返回该用户头像（如果头像确实存在的话），否则
     *                                      将据客户端提交上来的可能的本地缓存文件来判断是否需要下载用户头像（用户头像没有被更新过当然就不需要下载了！）
     * @param onePixelTransparentIfNo       此参数为“true”时，表示当用户没有设置头像时，会默认返回一个1像素透明图片（这主要用于Web网
     *                                      页里显示用户头像时，否则当用户没有设置头像时，因为没有图片数据返回而会在页面上显示一个“破图”img元素，那就难看死了！）
     * @throws IOException
     */
    private void processAvatarDownload(HttpServletResponse res
            , String userUid, String userLocalCachedAvatarFileName
            , boolean enforceDawnload, boolean onePixelTransparentIfNo) throws IOException {
        String avatarCurrentFileName = null;
        try {
            avatarCurrentFileName = LogicProcessor2.db.querySingleItem(
                    "Select user_avatar_file_name from missu_users where user_uid='" + userUid + "'");

            boolean avatarNotExsitsOrNotSetup = true;

            // 头像文件名不为空，即表示此用户设置过头像，为用户下载此头像文件即可
            if (!CommonUtils.isStringEmpty(avatarCurrentFileName, true)) {
                LoggerFactory.getLog().info("[HTTP]用户【" + userUid + "】的头像已被设置过，头像文件名：" + avatarCurrentFileName);

                // 如果不是强迫下载（即客户端有缓存机制情况但看服务端头像是否更新的情况）
                if (!enforceDawnload && userLocalCachedAvatarFileName != null) {
                    // 客户端当前缓存着的用户头像跟数据库里是一样的，就意味着该用户没有更新过头像，不需要重新返回逻
                    if (userLocalCachedAvatarFileName.toLowerCase().equals(avatarCurrentFileName)) {
                        LoggerFactory.getLog().info("[HTTP]用户【" + userUid + "】缓存在本地的头像" + avatarCurrentFileName + "已是最新的，无需下载.");
                        avatarNotExsitsOrNotSetup = false;
                        return;
                    }
                }

                String fileFullPath = BaseConf.getInstance().getDIR_USER_AVATAR_UPLOAD() + avatarCurrentFileName;

                if (!com.eva.epc.common.file.FileHelper.isFileExist(fileFullPath) && onePixelTransparentIfNo) {
                    avatarNotExsitsOrNotSetup = true;
                    LoggerFactory.getLog().info("[HTTP]用户【" + userUid + "】的头像文件" + avatarCurrentFileName
                            + "并不存在！接下将提供默认的1像素透明图片作为默认图，保证web端显示时不会太丑！");
                } else {
                    LoggerFactory.getLog().info("[HTTP]用户【" + userUid + "】缓存在本地的头像" + userLocalCachedAvatarFileName
                            + "(null表示用户本地无缓存)需要更新，下载立即开始 ......");
                    // 实施用户头像下载
                    FileDownload.download(res
                            , BaseConf.getInstance().getDIR_USER_AVATAR_UPLOAD() + avatarCurrentFileName
                            , avatarCurrentFileName
                            , FileDownload.CONTENT_TYPE_JPEG
                            , false);

                    avatarNotExsitsOrNotSetup = false;

                    return;
                }
            }

            // 此用户没有设置过头像或者已设置过但头像文件不存在于服务器磁盘上（这一般是迁移数据时忘记迁移图片文件了）
            if (avatarNotExsitsOrNotSetup)
//			else
            {
                LoggerFactory.getLog().warn("[HTTP]对不起,用户【" + userUid + "】的头像(avatarCurrentFileName=" + avatarCurrentFileName + ")不存在！");

                // 此参数为“true”时，表示当用户没有设置头像时，会默认返回一个1像素透明图片（这主要
                // 用于Web网页里显示用户头像时，否则当用户没有设置头像时，因为没有图片数据返回而会
                // 在页面上显示一个“破图”img元素，那就难看死了！）
                if (onePixelTransparentIfNo) {
                    File onePixelTransparentAvatarImg = new File(UserAvatarDownloader.class
                            .getResource(ONE_PIXEL_TRANSPARENT_AVATAR_FILE_NAME).toURI());
                    FileDownload.download(res
                            , onePixelTransparentAvatarImg
                            , ONE_PIXEL_TRANSPARENT_AVATAR_FILE_NAME
                            , FileDownload.CONTENT_TYPE_JPEG
                            , false);
                }
            }
        } catch (Exception e) {
            LoggerFactory.getLog().warn("[HTTP]用户【" + userUid + "】的头像文件不存在，本次下载已提前结束(" + e.getMessage() + ")");
        }
    }
}
